﻿local mod	= DBM:NewMod(333, "DBM-DragonSoul", nil, 187)
local L		= mod:GetLocalizedStrings()
local sndWOP	= mod:NewSound(nil, "SoundWOP", true)
local sndJS		= mod:NewSound(nil, "SoundWOP", true)

mod:SetRevision(("$Revision: 7389 $"):sub(12, -3))
mod:SetCreatureID(56173)
mod:SetModelID(40087)
mod:SetZone()
mod:SetUsedIcons(8)
mod:SetModelSound("Sound\\CREATURE\\Deathwing\\VO_DS_DEATHWING_MAELSTROMEVENT_01.wav", "Sound\\CREATURE\\Deathwing\\VO_DS_DEATHWING_MAELSTROMAGGRO_01.wav")

mod:RegisterCombat("yell", L.Pull)
mod:SetMinCombatTime(20)

mod:RegisterEventsInCombat(
	"SPELL_CAST_START",
	"SPELL_CAST_SUCCESS",
	"SPELL_AURA_APPLIED",
	"SPELL_AURA_APPLIED_DOSE",
	"SPELL_AURA_REMOVED",
	"SPELL_SUMMON",
	"UNIT_DIED",
	"RAID_BOSS_EMOTE",
	"UNIT_SPELLCAST_SUCCEEDED"
)

local warnMutated				= mod:NewSpellAnnounce("ej4112", 3, 467)
local warnImpale				= mod:NewTargetAnnounce(106400, 3, nil, mod:IsTank() or mod:IsHealer()) --刺穿
local warnElementiumBolt		= mod:NewSpellAnnounce(105651, 4) --源質箭
local warnTentacle				= mod:NewSpellAnnounce(105551, 3) --生成極熾觸手
local warnHemorrhage			= mod:NewSpellAnnounce(105863, 3) --出血
local warnCataclysm				= mod:NewCastAnnounce(106523, 4) --災變 60s
local warnPhase2				= mod:NewPhaseAnnounce(2, 3)
local warnFragments				= mod:NewSpellAnnounce("ej4115", 4, 106708)--This needs a custom spell icon, EJ doesn't have icons for entires that are mobs
local warnTerror				= mod:NewSpellAnnounce("ej4117", 4, 106765)--This needs a fitting spell icon, trigger spell only has a gear.
local warnShrapnel				= mod:NewTargetAnnounce(109598, 3, nil, false)
local warnParasite				= mod:NewTargetAnnounce(108649, 4)
local warnTetanus				= mod:NewStackAnnounce(109605, 4, nil, false)
local warnCongealingBloodSoon	= mod:NewSoonAnnounce("ej4350", 4, 109089)--15%, 10%, 5% on heroic. spellid is 109089.

local specWarnMutated			= mod:NewSpecialWarningSwitch("ej4112", not mod:IsHealer())--Because tanks need to switch to it too.
local specWarnImpale			= mod:NewSpecialWarningYou(106400)
local specWarnImpaleOther		= mod:NewSpecialWarningTarget(106400, mod:IsTank() or mod:IsHealer())
local specWarnElementiumBolt	= mod:NewSpecialWarningSpell(105651)--Cast, helps you find the mark on ground and get into positions
local specWarnElementiumBoltDPS	= mod:NewSpecialWarningSwitch(105651, mod:IsDps())--Warning for when to switch to dps it, because i really felt one warning didn't serve both meanings, one is an aoe/damage warning for cast, other should be specifically yelling at dps to kill it.
local specWarnTentacle			= mod:NewSpecialWarningSwitch("ej4103", mod:IsDps())--Tanks not included in this one cause they may still have adds.
local specWarnHemorrhage		= mod:NewSpecialWarningSpell(105863, not mod:IsHealer())--Because tanks need to switch to it too.
local specWarnFragments			= mod:NewSpecialWarningSpell("ej4115", mod:IsDps())--Not a "switch" warning because on normal a lot of groups choose to ignore these if they can burn boss and just pop dream. Let the raid leader decide strat on this one, not DBM.
local specWarnTerror			= mod:NewSpecialWarningSpell("ej4117")--Same as fragments.
local specWarnShrapnel			= mod:NewSpecialWarningYou(109598)
local specWarnParasite			= mod:NewSpecialWarningYou(108649)
local specWarnParasiteOther		= mod:NewSpecialWarningTarget(108649, mod:IsHealer())
local specWarnParasiteDPS		= mod:NewSpecialWarningSwitch("ej4347", mod:IsDps())
local yellParasite				= mod:NewYell(108649)
local specWarnCongealingBlood	= mod:NewSpecialWarningSwitch("ej4350", mod:IsDps())--15%, 10%, 5% on heroic. spellid is 109089.
local specWarnTetanus			= mod:NewSpecialWarningStack(109605, mod:IsTank(), 4)
local specWarnTetanusOther		= mod:NewSpecialWarningTarget(109605, mod:IsTank())

local specWarnjs				= mod:NewSpecialWarning("SpecWarnjs")

local timerMutated				= mod:NewNextTimer(17, "ej4112", nil, nil, nil, 467)--use druid spell Thorns icon temporarily.
local timerImpale				= mod:NewTargetTimer(49.5, 106400, nil, mod:IsTank() or mod:IsHealer())--45 plus 4 second cast plus .5 delay between debuff ID swap.
local timerImpaleCD				= mod:NewCDTimer(35, 106400, nil, mod:IsTank() or mod:IsHealer())
local timerElementiumCast		= mod:NewCastTimer(7.5, 105651)
local timerElementiumBlast		= mod:NewCastTimer(8, 109600)--8-10 variation depending on where it's actually going to land. Use the min time.
local timerElementiumBoltCD		= mod:NewNextTimer(55.5, 105651)
local timerHemorrhageCD			= mod:NewCDTimer(100.5, 105863)
local timerCataclysm			= mod:NewCastTimer(60, 106523)
local timerCataclysmCD			= mod:NewCDTimer(130.5, 106523)--130.5-131.5 variations
local timerFragmentsCD			= mod:NewNextTimer(90, "ej4115", nil, nil, nil, 106708)--Gear icon for now til i find something more suitable
local timerTerrorCD				= mod:NewNextTimer(90, "ej4117", nil, nil, nil, 106765)--^
local timerShrapnel				= mod:NewBuffFadesTimer(6, 109598)
local timerParasite				= mod:NewTargetTimer(10, 108649)
local timerParasiteCD			= mod:NewCDTimer(60, 108649)
local timerUnstableCorruption	= mod:NewCastTimer(10, 108813)
local timerTetanus				= mod:NewTargetTimer(6, 109605, nil, mod:IsHealer())
local timerTetanusCD			= mod:NewCDTimer(3.5, 109605, nil, mod:IsTank())

local berserkTimer				= mod:NewBerserkTimer(900)

mod:AddBoolOption("RangeFrame", true)--For heroic parasites, with debuff filtering.
mod:AddBoolOption("SetIconOnParasite", true)
mod:AddBoolOption("SoundJS", true, "sound")

mod:AddDropdownOption("optjs", {"non", "mushi1", "mushi2", "shengqi1", "shengqi2", "shengqi3", "saman1", "saman2", "druid1", "druid2"}, "non", "sound")

local firstAspect = true
local engageCount = 1
local playerGUID = nil
local shrapnelTargets = {}
local antiSpam = 0
local warnedCount = 0
local hemorrhage = GetSpellInfo(105863)
local fragment = GetSpellInfo(109568)
local activateTetanusTimers = false
local EBtime = 11
local UCdebuff = false
local impcount = 0
local parcount = 0
local tentcount = 0

local debuffFilter
do
	debuffFilter = function(uId)
		return UnitDebuff(uId, GetSpellInfo(108649))
	end
end

function mod:updateRangeFrame()
	if not self.Options.RangeFrame then return end
	if UnitDebuff("player", GetSpellInfo(108649)) then
		DBM.RangeCheck:Show(10, nil)--Show everyone.
	else
		DBM.RangeCheck:Show(10, debuffFilter)--Show only people who have debuff.
	end
end

local function warnShrapnelTargets()
	warnShrapnel:Show(table.concat(shrapnelTargets, "<, >"))
	timerShrapnel:Start()
	table.wipe(shrapnelTargets)
end

function mod:OnCombatStart(delay)
	firstAspect = true
	activateTetanusTimers = false
	engageCount = 1
	antiSpam = 0
	warnedCount = 0
	UCdebuff = false
	impcount = 0
	parcount = 0
	tentcount = 0
	table.wipe(shrapnelTargets)
	berserkTimer:Start(-delay)
end

function mod:OnCombatEnd()
	if self.Options.RangeFrame then
		DBM.RangeCheck:Hide()
	end
	self:UnregisterShortTermEvents()
end

function mod:SPELL_CAST_START(args)
	if args:IsSpellID(107018) then
		if firstAspect then--The abilities all come 15seconds earlier for first one only
			firstAspect = false
			timerMutated:Start(11)
			warnMutated:Schedule(11)
			specWarnMutated:Schedule(11)
			timerImpaleCD:Start(22)
			timerElementiumBoltCD:Start(40.5)
			if self:IsDifficulty("heroic10", "heroic25") then
				timerHemorrhageCD:Start(55.5)--Appears to be 30 seconds earlier in heroic
				timerParasiteCD:Start(11)
			else
				timerHemorrhageCD:Start(85.5)
			end
			timerCataclysmCD:Start(115.5)
			sndWOP:Schedule(7, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cxzb.mp3")--觸鬚準備
			sndWOP:Schedule(8.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndWOP:Schedule(9.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndWOP:Schedule(10.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
			sndWOP:Schedule(11.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cxkd2.mp3")--觸鬚快打
		else
			timerMutated:Start()
			warnMutated:Schedule(17)
			specWarnMutated:Schedule(17)
			timerImpaleCD:Start(27.5)
			timerElementiumBoltCD:Start()
			if self:IsDifficulty("heroic10", "heroic25") then
				timerHemorrhageCD:Start(70.5)
				timerParasiteCD:Start(22)
			else
				timerHemorrhageCD:Start()
			end
			timerCataclysmCD:Start()
			sndWOP:Schedule(14, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cxzb.mp3")--觸鬚準備
			sndWOP:Schedule(15, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndWOP:Schedule(16, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndWOP:Schedule(17, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
			sndWOP:Schedule(18, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cxkd2.mp3")--觸鬚快打
		end
	elseif args:IsSpellID(106523, 110042, 110043, 110044) then
		warnCataclysm:Show()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_dzb.mp3")
		timerCataclysm:Start()
		sndWOP:Schedule(55, "Interface\\AddOns\\DBM-Core\\extrasounds\\countfive.mp3")
		sndWOP:Schedule(56, "Interface\\AddOns\\DBM-Core\\extrasounds\\countfour.mp3")
		sndWOP:Schedule(57, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
		sndWOP:Schedule(58, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
		sndWOP:Schedule(59, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		sndWOP:Schedule(60, "Interface\\AddOns\\DBM-Core\\extrasounds\\dead.mp3")
	elseif args:IsSpellID(108813) then
		if UCdebuff then
			timerUnstableCorruption:Start(15.5)
			sndJS:Schedule(12, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jszb.mp3")--寄生爆炸準備
			sndJS:Schedule(13, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndJS:Schedule(14, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndJS:Schedule(15, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		else
			timerUnstableCorruption:Start()
			sndJS:Schedule(6.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jszb.mp3")
			sndJS:Schedule(7.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndJS:Schedule(8.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndJS:Schedule(9.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		end
	end
end

function mod:SPELL_CAST_SUCCESS(args)
	if args:IsSpellID(105651) then
		warnElementiumBolt:Show()
		specWarnElementiumBolt:Show()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_yzjzb.mp3")--源質箭準備
		if mod.Options.optjs == "mushi1" and engageCount == 4 then
			self:Schedule(5, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("真言術:壁","源質箭")
			end)
		end
		if mod.Options.optjs == "saman1" and engageCount == 4 then
			self:Schedule(5, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("靈魂連接","源質箭")
			end)
		end
		if mod.Options.optjs == "druid1" and engageCount == 4 then
			self:Schedule(10, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("寧靜","源質箭")
			end)
		end
		if not UnitBuff("player", GetSpellInfo(109624)) and not UnitIsDeadOrGhost("player") then--Check for Nozdormu's Presence
			timerElementiumBlast:Start()
			specWarnElementiumBoltDPS:Schedule(EBtime)
			if not UnitBuff("player", GetSpellInfo(109642)) and not UnitIsDeadOrGhost("player") then
				sndWOP:Schedule(EBtime - 5, "Interface\\AddOns\\DBM-Core\\extrasounds\\aesoon.mp3")--準備AE
				sndWOP:Schedule(EBtime - 4, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
				sndWOP:Schedule(EBtime - 3, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
				sndWOP:Schedule(EBtime - 2, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
				sndWOP:Schedule(EBtime, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_yzjkd.mp3")--源質箭快打
			else
				sndWOP:Schedule(EBtime - 5, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_kjmj.mp3")--快進夢境
				sndWOP:Schedule(EBtime - 4, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
				sndWOP:Schedule(EBtime - 3, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
				sndWOP:Schedule(EBtime - 2, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
				sndWOP:Schedule(EBtime, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_yzjkd.mp3")--源質箭快打
			end
		else
			timerElementiumCast:Start()
			timerElementiumBlast:Start(17)
			specWarnElementiumBoltDPS:Schedule(7.5)
			sndWOP:Schedule(7, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_yzjkd.mp3")--源質箭快打
			if not UnitBuff("player", GetSpellInfo(109642)) and not UnitIsDeadOrGhost("player") then
				sndWOP:Schedule(EBtime + 5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
				sndWOP:Schedule(EBtime + 6, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
				sndWOP:Schedule(EBtime + 7, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
			else
				sndWOP:Schedule(EBtime + 4, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_kjmj.mp3")--快進夢境
				sndWOP:Schedule(EBtime + 5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
				sndWOP:Schedule(EBtime + 6, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
				sndWOP:Schedule(EBtime + 7, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
			end
		end
	elseif args:IsSpellID(110063) then--Astral Recall. Thrall teleports off back platform back to front on defeat.
		self:SendSync("MadnessDown")
	end
end

function checkUCdebuff()
	if UnitDebuff(playerGUID, GetSpellInfo(108646)) then
		UCdebuff = true
	end
end

function mod:SPELL_AURA_APPLIED(args)
	if args:IsSpellID(106548) then--Arm/Wing Transition
		engageCount = engageCount + 1
		parcount = 0
		tentcount = 0
		timerElementiumBoltCD:Cancel()
		timerHemorrhageCD:Cancel()--Does this one cancel in event you super overgear this and stomp his ass this fast?
		timerCataclysm:Cancel()
		timerCataclysmCD:Cancel()
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countfive.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countfour.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\dead.mp3")
	elseif args:IsSpellID(109592, 109593, 106834, 109594) then--Phase 2
		warnPhase2:Show()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ptwo.mp3")
		timerFragmentsCD:Start(10.5)
		timerTerrorCD:Start(35.5)
		if self:IsDifficulty("heroic10", "heroic25") then--Only register on heroic, we don't need on normal.
			self:RegisterShortTermEvents(
				"UNIT_HEALTH_FREQUENT"
			)
		end
	elseif args:IsSpellID(106400) then
		warnImpale:Show(args.destName)
		timerImpale:Start(args.destName)
		timerImpaleCD:Start()
		impcount = impcount + 1
		if mod:IsHealer() or mod:IsTank() then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cczb.mp3")--刺穿準備
		end
		if args:IsPlayer() then
			specWarnImpale:Show()
		else
			specWarnImpaleOther:Show(args.destName)
		end
		if mod.Options.optjs == "mushi1" and engageCount == 2 and impcount == 1 then
			self:Schedule(0.5, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("壓制","刺穿")
			end)
		end
		if mod.Options.optjs == "mushi2" and engageCount == 2 and impcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("壓制","刺穿")
			end)
		end
		if mod.Options.optjs == "druid2" and engageCount == 2 and impcount == 1 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("狂暴恢復","刺穿")
			end)
		end
		if mod.Options.optjs == "shengqi1" and (engageCount == 2 or engageCount == 4) and impcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("無敵犧牲","刺穿")
			end)
		end
		if mod.Options.optjs == "shengqi1" and engageCount == 3 and impcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("聖佑犧牲","刺穿")
			end)
		end
		if mod.Options.optjs == "shengqi2" and engageCount == 4 and impcount == 1 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("無敵犧牲","刺穿")
			end)
		end
		if mod.Options.optjs == "shengqi3" and impcount == 1 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("群體犧牲","刺穿")
			end)
		end
	elseif args:IsSpellID(106794, 110139, 110140, 110141) then
		shrapnelTargets[#shrapnelTargets + 1] = args.destName
		self:Unschedule(warnShrapnelTargets)
		if args:IsPlayer() then
			specWarnShrapnel:Show()
			timerShrapnel:Start()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_spzb.mp3")--碎片準備
			local _, _, _, _, _, duration, expires, _, _ = UnitDebuff("player", args.spellName)
			sndWOP:Schedule(expires - GetTime() - 5, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_kjmj.mp3")
			sndWOP:Schedule(expires - GetTime() - 4, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndWOP:Schedule(expires - GetTime() - 3, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndWOP:Schedule(expires - GetTime() - 2, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		end
		if (self:IsDifficulty("normal10", "heroic10") and #shrapnelTargets >= 3) or (self:IsDifficulty("normal25", "heroic25", "lfr25") and #shrapnelTargets >= 8) then
			warnShrapnelTargets()
		else
			self:Schedule(0.3, warnShrapnelTargets)
		end
	elseif args:IsSpellID(108649) then
		warnParasite:Show(args.destName)
		timerParasite:Start(args.destName)
		timerParasiteCD:Start()
		self:updateRangeFrame()
		parcount = parcount + 1
		if mod.Options.optjs == "mushi1" and engageCount == 4 and parcount == 1 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("壓制","寄生體")
			end)
		end
		if mod.Options.optjs == "shengqi2" and (engageCount == 1 or engageCount == 3) and parcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("聖佑犧牲","寄生體")
			end)
		end
		if mod.Options.optjs == "shengqi2" and engageCount == 2 and parcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("無敵犧牲","寄生體")
			end)
		end
		if mod.Options.optjs == "shengqi3" and (engageCount == 1 or engageCount == 2 or engageCount == 3) and parcount == 1 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("犧牲","寄生體")
			end)
		end
		if mod.Options.optjs == "mushi2" and engageCount == 4 and parcount == 2 then
			self:Schedule(1, function()
				sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
				specWarnjs:Show("壓制","寄生體")
			end)
		end
		if args:IsPlayer() then
			specWarnParasite:Show()
			yellParasite:Yell()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_js.mp3")--你被寄生
			if UnitBuff("player", GetSpellInfo(109642)) then
				sndWOP:Schedule(2, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_kjmj.mp3")
			end
			if engageCount == 3 and self.Options.SoundJS then
				sndWOP:Schedule(1, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_huang.mp3")
				specWarnjs:Schedule(1, "寄生體","黃圈")
			end
			sndWOP:Schedule(5.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countfive.mp3")
			sndWOP:Schedule(6.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countfour.mp3")
			sndWOP:Schedule(7.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndWOP:Schedule(8.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndWOP:Schedule(9.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		else
			specWarnParasiteOther:Show(args.destName)
			sndWOP:Schedule(5, "Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jsflzb.mp3")
			sndWOP:Schedule(6, "Interface\\AddOns\\DBM-Core\\extrasounds\\countfour.mp3")
			sndWOP:Schedule(7, "Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
			sndWOP:Schedule(8, "Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
			sndWOP:Schedule(9, "Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		end
		playerGUID = args.destName
		UCdebuff = false
		if self.Options.SetIconOnParasite then
			self:SetIcon(args.destName, 8)
		end
	elseif args:IsSpellID(106730, 109603, 109604, 109605) then -- Debuffs from adds
		warnTetanus:Show(args.destName, args.amount or 1)
		timerTetanus:Start(args.destName)
		if (args.amount or 1) >= 4 then
			if args:IsPlayer() then
				specWarnTetanus:Show(args.amount)
			else
				if not UnitIsDeadOrGhost("player") and not UnitDebuff("player", GetSpellInfo(109603)) then--You have no debuff and not dead
					specWarnTetanusOther:Show(args.destName)--So stop being a tool and taunt off other tank who has 4 stacks.
				end
			end
		end
		if activateTetanusTimers then -- Only track them when there is no Time Zone down (since we have no way to accurate track/detect whether or not they are tanked in it, ie slowed)
			timerTetanusCD:Start(args.sourceGUID)
		end
	end
end
mod.SPELL_AURA_APPLIED_DOSE = mod.SPELL_AURA_APPLIED


function mod:SPELL_AURA_REMOVED(args)
	if args:IsSpellID(106444, 109631, 109632, 109633) then
		timerImpale:Cancel(args.destName)
	elseif args:IsSpellID(106794, 110139, 110140, 110141) and args:IsPlayer() then
		timerShrapnel:Cancel()
	elseif args:IsSpellID(108649) then
		checkUCdebuff()
		specWarnParasiteDPS:Show()
		if UnitBuff("player", GetSpellInfo(106028)) and UCdebuff then			
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jsfl.mp3")--寄生分離
		else
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jskd.mp3")--寄生體快打
		end
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
		if self.Options.SetIconOnParasite then
			self:SetIcon(args.destName, 0)
		end
		if self.Options.RangeFrame then
			DBM.RangeCheck:Hide()
		end
	end
end

function mod:SPELL_SUMMON(args)
	if args:IsSpellID(109091) and GetTime() - antiSpam > 10 then
		antiSpam = GetTime()--Because they don't spawn at same time, a bunch spawn over about 7-8 sec, so we have to filter a ton of em.
		specWarnCongealingBlood:Show()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\killslime.mp3")--軟泥快打
	end
end

function mod:UNIT_DIED(args)
	local cid = self:GetCIDFromGUID(args.destGUID)
	if cid == 56471 then--Mutated Corruption
		timerImpaleCD:Cancel()
		timerParasiteCD:Cancel()
		timerImpale:Cancel()--Cancel impale debuff timers since they don't matter anymore until next platform (well after they cleared)
		impcount = 0
	elseif cid == 57479 then
		timerUnstableCorruption:Cancel()
		sndJS:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_jszb.mp3")
		sndJS:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
		sndJS:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
		sndJS:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
	elseif cid == 56311 then --Phase 2 Time Zone bubbles (yes it's an npc heh)
		activateTetanusTimers = true
	elseif cid == 56710 then
		timerTetanusCD:Cancel(args.destGUID)
	end
end

function mod:UNIT_SPELLCAST_SUCCEEDED(uId, spellName, _, _, spellId)
	if spellId == 110663 then--Elementium Meteor Transform (apparently this doesn't fire UNIT_DIED anymore, need to use this alternate method)
		self:SendSync("BoltDied")--Send sync because Elementium bolts do not have a bossN arg, which means event only fires if it's current target/focus.
	end
	if not uId:find("boss") then return end--Anti spam to ignore all other args (like target/focus/mouseover)
	if spellName == hemorrhage then
		warnHemorrhage:Show()
		specWarnHemorrhage:Show()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_zbrn.mp3")--準備軟泥
		if not self:IsDifficulty("heroic10", "heroic25") then
			sndWOP:Schedule(3.5, "Interface\\AddOns\\DBM-Core\\extrasounds\\killslime.mp3")--軟泥快打
		end
	elseif spellId == 105551 then--Spawn Blistering Tentacles
		if not UnitBuff("player", GetSpellInfo(106028)) and not UnitIsDeadOrGhost("player") then--Check for Alexstrasza's Presence
			warnTentacle:Show()
			specWarnTentacle:Show()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cskd.mp3")--觸手快打
		end
		tentcount = tentcount + 1
		if mod.Options.optjs == "saman1" and tentcount == 2 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("法潮","小霸")
		end
		if mod.Options.optjs == "mushi2" and (engageCount == 3 or engageCount == 4) and tentcount == 2 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("真言術:壁","極炙觸手")
		end
		if mod.Options.optjs == "shengqi1" and tentcount == 2 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("精通光環","極炙觸手")
		end
		if mod.Options.optjs == "saman1" and engageCount == 2 and tentcount == 1 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("靈魂鏈接","極炙觸手")
		end
		if mod.Options.optjs == "druid1" and engageCount == 2 and tentcount == 1 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("寧靜","極炙觸手")
		end
		if mod.Options.optjs == "saman2" and (engageCount == 2 or engageCount == 3 or engageCount == 4) and tentcount == 2 then
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\didi.mp3")
			specWarnjs:Show("靈魂鏈接","極炙觸手")
		end
	elseif spellName == fragment then--Summon Impaling Tentacle (Fragments summon)
		warnFragments:Show()
		specWarnFragments:Show()
		timerFragmentsCD:Start()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_cxkd2.mp3")--觸鬚快打
	elseif spellId == 106765 then--Summon Elementium Terror (Big angry add)
		activateTetanusTimers = false
		warnTerror:Show()
		specWarnTerror:Show()
		timerTerrorCD:Start()
		sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_yzkj.mp3")--源質恐懼刷新
	end
end

function mod:OnSync(msg)
	if msg == "BoltDied" then
		timerElementiumBlast:Cancel()--Lot of work just to cancel a timer, why the heck did blizz break this mob firing UNIT_DIED when it dies? Sigh.
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\aesoon.mp3")--取消源質箭計時
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_kjmj.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countthree.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\counttwo.mp3")
		sndWOP:Cancel("Interface\\AddOns\\DBM-Core\\extrasounds\\countone.mp3")
	elseif msg == "MadnessDown" and self:IsInCombat() then
		DBM:EndCombat(self)
	end
end

function mod:UNIT_HEALTH_FREQUENT(uId)
	if uId == "boss1" then
		local hp = UnitHealth(uId) / UnitHealthMax(uId) * 100
		if hp > 15 and hp < 16.2 and warnedCount == 0 then
			warnedCount = 1
			warnCongealingBloodSoon:Show()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_zbrn.mp3")--準備軟泥
		elseif hp > 10 and hp < 11.2 and warnedCount == 1 then
			warnedCount = 2
			warnCongealingBloodSoon:Show()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_zbrn.mp3")--準備軟泥
		elseif hp > 5 and hp < 6.2 and warnedCount == 2 then
			warnedCount = 3
			warnCongealingBloodSoon:Show()
			sndWOP:Play("Interface\\AddOns\\DBM-Core\\extrasounds\\ex_ds_zbrn.mp3")--準備軟泥
			self:UnregisterShortTermEvents()
		end
	end
end

function mod:RAID_BOSS_EMOTE(msg) --判定在哪個臺子上打以調整源質箭時間
	if msg == L.Red or msg:find(L.Red) then
		EBtime = 10.5
	elseif msg == L.Yellow or msg:find(L.Yellow) then
		EBtime = 9.5
	elseif msg == L.Blue or msg:find(L.Blue) then		
		EBtime = 9
	elseif msg == L.Green or msg:find(L.Green) then
		EBtime = 9.5
	end
end